package com.eight.service.impl;

import cn.hutool.core.lang.ObjectId;
import cn.hutool.core.lang.UUID;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.eight.dao.OrderMapper;
import com.eight.feign.AliPayFeign;
import com.eight.feign.CouponHistoryFeign;
import com.eight.feign.RabbitFeign;
import com.eight.feign.UserFeign;
import com.eight.pojo.TbCar;
import com.eight.pojo.TbOrder;
import com.eight.service.CarInformationService;
import com.eight.service.OrderService;
import com.eight.util.TimeUtil;
import com.eight.util.WeChatPayUtil;
import com.eight.vo.CarOrderVo;
import com.eight.vo.ComResult;
import com.eight.vo.OrderPayVo;
import com.eight.vo.WeChatComData;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, TbOrder> implements OrderService {

    @Autowired
    OrderMapper orderMapper;
    @Autowired
    private UserFeign userFeign;
    @Autowired
    private RabbitFeign rabbitFeign;
    @Autowired
    private AliPayFeign aliPayFeign;
    @Autowired
    private StringRedisTemplate redis;
    @Autowired
    private CouponHistoryFeign couponHistoryFeign;
    @Autowired
    private CarInformationService carInformationService;


    /**
     * @param page
     * @param size
     * @param tbOrder
     * @return
     */
    @Override
    public PageInfo<TbOrder> queryAllOrder(Integer page, Integer size, TbOrder tbOrder) {
        System.out.println(tbOrder);
        PageHelper.startPage(page, size);
        List<TbOrder> tbOrders = orderMapper.queryAllOrder(tbOrder.getOrderNo());
        return new PageInfo<>(tbOrders);
    }

    @Override
    @Transactional
    public ComResult makeOrder(CarOrderVo carOrderVo) {
        // 生产租车订单信息
        TbOrder tbOrder = new TbOrder();
        String uuid = UUID.fastUUID().toString();
        tbOrder.setOrderNo(uuid);
        tbOrder.setAddtime(TimeUtil.now(""));
        tbOrder.setCarId(carOrderVo.getCarId());
        tbOrder.setBrrowShop(carOrderVo.getBrrowShop());
        tbOrder.setReturnShop(carOrderVo.getReturnShop());
        tbOrder.setEndTime(carOrderVo.getEndTime().atTime(0, 0));
        tbOrder.setUsername(carOrderVo.getUsername());
        tbOrder.setClientId(carOrderVo.getUserId());
        tbOrder.setTotalPrice(carOrderVo.getPrice());
        tbOrder.setGetCarLocation(carOrderVo.getBrrowLocale());
        tbOrder.setReturnCarLocation(carOrderVo.getRentLocale());
        tbOrder.setState(1);

        tbOrder.setStartTime(carOrderVo.getStartTime().atTime(0, 0));
        int oi = orderMapper.insert(tbOrder);
        // 然后删掉优惠券
        int ui = 2;
        if (carOrderVo.getCouponId() != -1) {
            ui = userFeign.deleteUserCon(carOrderVo.getUsername(), carOrderVo.getCouponId());
            int i = couponHistoryFeign.insertIntegrationHistory(carOrderVo.getUsername(), carOrderVo.getCouponId(), 2);
        }
        // 修改车辆状态
        carInformationService.updateCar(new TbCar().setId(carOrderVo.getCarId()).setState(0));
        // 然后减去金额
        int mi = userFeign.deleteMoney(carOrderVo.getUsername(), carOrderVo.getPrice().doubleValue());
        System.out.println("oi" + oi);
        System.out.println("ui" + ui);
        System.out.println("mi" + mi);
        if (oi > 0 && ui > 0 && mi > 0) {
            return new ComResult(2000, "更新成功", tbOrder
            );
        } else {
            throw new RuntimeException("出现错误需要回滚！");
        }
    }

    /**
     * 实现支付宝下订单的业务
     *
     * @param carOrderVo 订单信息
     * @return 下订单结果
     */
    @Override
    public ComResult productionAliPay(CarOrderVo carOrderVo) {
        // 生产租车订单信息
        TbOrder tbOrder = new TbOrder();
        String uuid = UUID.fastUUID().toString();
        tbOrder.setOrderNo(uuid);
        tbOrder.setAddtime(TimeUtil.now(""));
        tbOrder.setCarId(carOrderVo.getCarId());
        tbOrder.setBrrowShop(carOrderVo.getBrrowShop());
        tbOrder.setReturnShop(carOrderVo.getReturnShop());
        tbOrder.setEndTime(carOrderVo.getEndTime().atTime(0, 0));
        tbOrder.setUsername(carOrderVo.getUsername());
        tbOrder.setClientId(carOrderVo.getUserId());
        tbOrder.setTotalPrice(carOrderVo.getPrice());
        tbOrder.setGetCarLocation(carOrderVo.getBrrowLocale());
        tbOrder.setReturnCarLocation(carOrderVo.getRentLocale());
        tbOrder.setState(0);
        tbOrder.setStartTime(carOrderVo.getStartTime().atTime(0, 0));
        // 插入订单数据
        int oi = orderMapper.insert(tbOrder);
        int i1 = carInformationService.updateCarById(carOrderVo.getCarId());
        // 然后删掉优惠券
        int ui = 2;
        if (carOrderVo.getCouponId() != -1) {
            ui = userFeign.deleteUserCon(carOrderVo.getUsername(), carOrderVo.getCouponId());
            // 插入优惠券记录
            int i = couponHistoryFeign.insertIntegrationHistory(carOrderVo.getUsername(), carOrderVo.getCouponId(), 2);

        }
        carInformationService.updateCar(new TbCar().setId(carOrderVo.getCarId()).setState(0));
        // 往rabbitMq推送消息
        rabbitFeign.makeCarOrder(tbOrder.getOrderNo());
        // 最后生产二维码,这里我们要准备二维码地址来返回给前端
        OrderPayVo orderPayVo = new OrderPayVo();
        orderPayVo.setOrderNo(tbOrder.getOrderNo());
        orderPayVo.setPreparidAmount(tbOrder.getTotalPrice().doubleValue());
        ComResult alipay = aliPayFeign.aliPay(orderPayVo);
        return new ComResult(2000, tbOrder.getOrderNo(), alipay.getData());
    }

    /**
     * 校验支付状态
     *
     * @param orderPayVo 订单的信息
     * @return 状态结果
     */
    @Override
    public ComResult checkOrderStatu(OrderPayVo orderPayVo) {
        boolean pay = aliPayFeign.isPay(orderPayVo);
        System.out.println(pay);
        //  若已经支付就通知消费掉她
        if (pay) {
            redis.opsForValue().set(orderPayVo.getOrderNo(), orderPayVo.getOrderNo(), 5, TimeUnit.MINUTES);
        }
        return pay ? new ComResult(2000, "支付成功") : new ComResult(5000, "支付失败");
    }

    /**
     * 实现微信下单的业务
     *
     * @param carOrderVo
     * @return
     */
    @Override
    public ComResult productionWxPay(CarOrderVo carOrderVo) {
        TbOrder tbOrder = new TbOrder();
        String uuid = ObjectId.next();
        tbOrder.setOrderNo(uuid);
        tbOrder.setAddtime(TimeUtil.now(""));
        tbOrder.setCarId(carOrderVo.getCarId());
        tbOrder.setBrrowShop(carOrderVo.getBrrowShop());
        tbOrder.setReturnShop(carOrderVo.getReturnShop());
        tbOrder.setEndTime(carOrderVo.getEndTime().atTime(0, 0));
        tbOrder.setUsername(carOrderVo.getUsername());
        tbOrder.setClientId(carOrderVo.getUserId());
        tbOrder.setTotalPrice(carOrderVo.getPrice());
        tbOrder.setGetCarLocation(carOrderVo.getBrrowLocale());
        tbOrder.setReturnCarLocation(carOrderVo.getRentLocale());
        tbOrder.setState(0);
        tbOrder.setStartTime(carOrderVo.getStartTime().atTime(0, 0));

        int wxoi = orderMapper.insert(tbOrder);
        int i1 = carInformationService.updateCarById(carOrderVo.getCarId());
        int ui = 2;
        if (carOrderVo.getCouponId() != -1) {
            ui = userFeign.deleteUserCon(carOrderVo.getUsername(), carOrderVo.getCouponId());
            int i = couponHistoryFeign.insertIntegrationHistory(carOrderVo.getUsername(), carOrderVo.getCouponId(), 2);
        }
        rabbitFeign.makeCarOrder(tbOrder.getOrderNo());
        carInformationService.updateCar(new TbCar().setId(carOrderVo.getCarId()).setState(0));
        //生成二维码,返回给前端
        WeChatComData weChatComData = new WeChatComData();
        weChatComData.setAmount(tbOrder.getTotalPrice());
        weChatComData.setTitle(tbOrder.getOrderNo());
        weChatComData.setSerialNumber(tbOrder.getOrderNo());

        WeChatComData chatComData = WeChatPayUtil.makePayOrder(weChatComData);

        return new ComResult(2000, "生成微信二维码成功", chatComData);
    }


    @Override
    public ComResult checkOrderStatus(OrderPayVo orderPayVo) {
        boolean queryPayStatus = WeChatPayUtil.queryPayStatus(orderPayVo.getOrderNo());
        if (queryPayStatus) {
            redis.opsForValue().set(orderPayVo.getOrderNo(), orderPayVo.getOrderNo(), 5, TimeUnit.MINUTES);
        }
        return queryPayStatus ? new ComResult(2000, "支付成功") : new ComResult(5000, "支付失败");
    }


}
